﻿using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Revit;

namespace YArchitech.HVAC
{
	public class PipeInsulationManage
	{
		public PipeInsulationManage(UIDocument uiDocument)
		{
			this.uiDoc = uiDocument;
		}

		public bool AddPipesInsulationLayer(PipeInsulationType insulationType, Dictionary<Pipe, double> dic)
		{
			bool result = true;
			try
			{
				foreach (KeyValuePair<Pipe, double> keyValuePair in dic)
				{
					double num = keyValuePair.Value / 304.8;
					Parameter parameter = keyValuePair.Key.GetParameter(BuiltInParameter.RBS_REFERENCE_INSULATION_THICKNESS);
					if (num >= 0.0032808398950131233 && parameter.AsDouble() <= 0.0)
					{
						PipeInsulation.Create(this.uiDoc.Document, keyValuePair.Key.Id, insulationType.Id, num);
					}
				}
				foreach (KeyValuePair<FamilyInstance, double> keyValuePair2 in this.GetFamilyInstanceInsulationLayer(dic))
				{
					double num2 = keyValuePair2.Value / 304.8;
					Parameter parameter2 = keyValuePair2.Key.GetParameter(BuiltInParameter.RBS_REFERENCE_INSULATION_THICKNESS);
					if (num2 >= 0.0032808398950131233 && parameter2.AsDouble() <= 0.0)
					{
						PipeInsulation.Create(this.uiDoc.Document, keyValuePair2.Key.Id, insulationType.Id, num2);
					}
				}
			}
			catch (Exception ex)
			{
				ex.ToString();
				result = false;
			}
			return result;
		}

		private Dictionary<FamilyInstance, double> GetFamilyInstanceInsulationLayer(Dictionary<Pipe, double> dic)
		{
			Dictionary<FamilyInstance, double> dictionary = new Dictionary<FamilyInstance, double>();
			foreach (FamilyInstance familyInstance in this.allInstances)
			{
				List<Pipe> familyInstanceConnedPipes = this.GetFamilyInstanceConnedPipes(familyInstance);
				if (familyInstanceConnedPipes != null && familyInstanceConnedPipes.Count >= 1)
				{
					double valveThick = this.GetValveThick(dic, familyInstanceConnedPipes);
					dictionary.Add(familyInstance, valveThick);
				}
			}
			return dictionary;
		}

		private double GetValveThick(Dictionary<Pipe, double> dic, List<Pipe> listPipe)
		{
			double num = 0.0;
			foreach (KeyValuePair<Pipe, double> keyValuePair in dic)
			{
				if (this.BeContains(listPipe, keyValuePair.Key) && num < keyValuePair.Value)
				{
					num = keyValuePair.Value;
				}
			}
			return num;
		}

		private bool BeContains(List<Pipe> listPipe, Pipe pipe)
		{
			bool result = false;
			using (List<Pipe>.Enumerator enumerator = listPipe.GetEnumerator())
			{
				while (enumerator.MoveNext())
				{
					if (enumerator.Current.Id.IntegerValue == pipe.Id.IntegerValue)
					{
						result = true;
						break;
					}
				}
			}
			return result;
		}

		private List<Pipe> GetFamilyInstanceConnedPipes(FamilyInstance fi)
		{
			List<Pipe> list = new List<Pipe>();
			foreach (Connector conn in YJKRevitTools.GetElementConnector(fi, (Autodesk.Revit.DB.Domain)3))
			{
				Pipe connedPipe = this.GetConnedPipe(conn);
				if (connedPipe != null)
				{
					list.Add(connedPipe);
				}
			}
			return list;
		}

		private Pipe GetConnedPipe(Connector conn)
		{
			Pipe result = null;
			Connector connectConnector = YJKRevitTools.GetConnectConnector(conn);
			Element owner = connectConnector.Owner;
			if (owner is Pipe)
			{
				result = (owner as Pipe);
			}
			else if (owner is FamilyInstance)
			{
				foreach (Connector connector in YJKRevitTools.GetElementConnector(owner as FamilyInstance, (Autodesk.Revit.DB.Domain)3))
				{
					if (!connector.Origin.IsAlmostEqualTo(connectConnector.Origin, 1E-05))
					{
						connectConnector = YJKRevitTools.GetConnectConnector(connector);
						owner = connectConnector.Owner;
						if (owner is Pipe)
						{
							result = (owner as Pipe);
							break;
						}
					}
				}
			}
			return result;
		}

		public string GetPipeSystem()
		{
			string result = "";
			try
			{
				Selection selection = this.uiDoc.Selection;
				Document document = this.uiDoc.Document;
				Reference reference = selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element, new PipeFilter(), "请选择管道系统……");
				result = (document.GetElementByRef(reference) as Pipe).GetSystemName();
			}
			catch (Exception ex)
			{
				ex.ToString();
			}
			return result;
		}

		public List<Pipe> GetCalcInsulationPipes(string systemName)
		{
			Selection selection = this.uiDoc.Selection;
			List<Pipe> list = new List<Pipe>();
			this.allInstances = new List<FamilyInstance>();
			try
			{
				foreach (Element element in selection.PickElementsByRectangle(new PipeFilterBySystemName(systemName), "请框选需要添加保温层的管道……"))
				{
					if (element is Pipe)
					{
						list.Add(element as Pipe);
					}
					if (element is FamilyInstance)
					{
						this.allInstances.Add(element as FamilyInstance);
					}
				}
				list = list.Distinct(new PipeComparer()).ToList<Pipe>();
			}
			catch (Exception ex)
			{
				ex.ToString();
				throw ex;
			}
			return list;
		}

		public void GetInterfaceSetting(ref double mediumTemp, ref double designTemp, ref double dewingTemp, ref InsulationLayerParam insulationParam, FormPipeInsulationLayer formInsulation)
		{
			mediumTemp = formInsulation.GetMediumTemp();
			designTemp = formInsulation.GetDesignTemp();
			dewingTemp = formInsulation.GetDewingTemp();
			insulationParam = formInsulation.GetSettingMaterial();
		}

		public void GetInterfaceSetting(ref double mediumTemp, ref double designTemp, ref double dewingTemp, ref InsulationLayerParam insulationParam, FormCreatPipeInsulation formInsulation)
		{
			mediumTemp = formInsulation.GetMediumTemp();
			designTemp = formInsulation.GetDesignTemp();
			dewingTemp = formInsulation.GetDewingTemp();
			insulationParam = formInsulation.GetSettingMaterial();
		}

		public void GetInterfaceSetting(ref double mediumTemp, ref double designTemp, ref double dewingTemp, ref InsulationLayerParam insulationParam, FormDuctInsulationLayer formInsulation)
		{
			mediumTemp = formInsulation.GetMediumTemp();
			designTemp = formInsulation.GetDesignTemp();
			dewingTemp = formInsulation.GetDewingTemp();
			insulationParam = formInsulation.GetSettingMaterial();
		}

		public void CreatInsulationType()
		{
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.uiDoc.Document);
			filteredElementCollector.OfClass(typeof(PipeInsulationType));
			List<InsulationLayerParam> allInsulationMaterials = new OperationLocation("").GetAllInsulationMaterials();
			List<Element> list = filteredElementCollector.ToList<Element>();
			if (list == null || list.Count < 1)
			{
				return;
			}
			SubTransaction subTransaction = new SubTransaction(this.uiDoc.Document);
			try
			{
				subTransaction.Start();
				foreach (InsulationLayerParam insulationLayerParam in allInsulationMaterials)
				{
					if (!this.BeExsit(list, insulationLayerParam))
					{
						(list.First<Element>() as PipeInsulationType).Duplicate(insulationLayerParam.Name);
					}
				}
				subTransaction.Commit();
			}
			catch (Exception ex)
			{
				ex.ToString();
				subTransaction.RollBack();
			}
		}

		public PipeInsulationType GetInsulationTypeByName(string materialName)
		{
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.uiDoc.Document);
			filteredElementCollector.OfClass(typeof(PipeInsulationType));
			IEnumerator<Element> enumerator = filteredElementCollector.GetEnumerator();
			enumerator.Reset();
			PipeInsulationType result = null;
			while (enumerator.MoveNext())
			{
				if (enumerator.Current.Name.Equals(materialName))
				{
					result = (enumerator.Current as PipeInsulationType);
				}
			}
			return result;
		}

		private bool BeExsit(List<Element> listType, InsulationLayerParam material)
		{
			bool result = false;
			foreach (Element element in listType)
			{
				if (material.Name.Equals(element.Name))
				{
					result = true;
					break;
				}
			}
			return result;
		}

		private UIDocument uiDoc;

		private List<FamilyInstance> allInstances;
	}
}
